package com.yingsheng.bi.hks.basic.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * Java 日期工具类
 *
 * @author root
 */
public class DateUtils {

    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
    public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter COMPACT_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
    public static final DateTimeFormatter COMPACT_TIME_FORMATTER = DateTimeFormatter.ofPattern("HHmmss");
    public static final DateTimeFormatter COMPACT_DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    /**
     * 获取当前日期字符串，格式为 "yyyy-MM-dd"
     *
     * @return 当前日期字符串
     */
    public static String currDate() {
        return LocalDate.now().format(DATE_FORMATTER);
    }

    /**
     * 获取当前日期字符串，格式为 "yyyyMMdd"
     *
     * @return 当前日期字符串
     */
    public static String currentCompactDate() {
        return LocalDate.now().format(COMPACT_DATE_FORMATTER);
    }

    /**
     * 获取当前时间字符串，默认格式为 "HH:mm:ss"
     *
     * @return 当前时间字符串
     */
    public static String currentTime() {
        return LocalTime.now().format(TIME_FORMATTER);
    }

    /**
     * 获取当前时间字符串，格式为 "HHmmss"
     *
     * @return 当前时间字符串
     */
    public static String currentCompactTime() {
        return LocalTime.now().format(COMPACT_TIME_FORMATTER);
    }

    /**
     * 获取当前日期时间字符串，默认格式为 "yyyy-MM-dd HH:mm:ss"
     *
     * @return 当前日期时间字符串
     */
    public static String currentDateTime() {
        return LocalDateTime.now().format(DATETIME_FORMATTER);
    }

    /**
     * 获取当前日期时间字符串，默认格式为 "yyyy-MM-dd HH:mm:ss"
     *
     * @return 当前日期时间字符串
     */
    public static String currentCompactDateTime() {
        return LocalDateTime.now().format(COMPACT_DATETIME_FORMATTER);
    }

    /**
     * 将日期字符串解析为 LocalDate 对象
     *
     * @param dateStr 日期字符串
     * @return 解析后的 LocalDate 对象
     */
    public static LocalDate parseDate(String dateStr) {
        return LocalDate.parse(dateStr, DATE_FORMATTER);
    }

    /**
     * 将时间字符串解析为 LocalTime 对象
     *
     * @param timeStr 时间字符串
     * @return 解析后的 LocalTime 对象
     */
    public static LocalTime parseTime(String timeStr) {
        return LocalTime.parse(timeStr, TIME_FORMATTER);
    }

    /**
     * 将日期时间字符串解析为 LocalDateTime 对象
     *
     * @param dateTimeStr 日期时间字符串
     * @return 解析后的 LocalDateTime 对象
     */
    public static LocalDateTime parseDateTime(String dateTimeStr) {
        return LocalDateTime.parse(dateTimeStr, DATETIME_FORMATTER);
    }

    /**
     * 格式化 LocalDate 对象为字符串，格式为yyyy-MM-dd
     *
     * @param localDate LocalDate 对象
     * @return 格式化后的日期字符串
     */
    public static String formatDate(LocalDate localDate) {
        return localDate.format(DATE_FORMATTER);
    }

    /**
     * 格式化 LocalDate 对象为字符串，格式为yyyyMMdd
     *
     * @param localDate LocalDate 对象
     * @return 格式化后的日期字符串
     */
    public static String formatCompactDate(LocalDate localDate) {
        return localDate.format(COMPACT_DATE_FORMATTER);
    }

    /**
     * 格式化 LocalTime 对象为字符串，格式为HH:mm:ss
     *
     * @param localTime LocalTime 对象
     * @return 格式化后的时间字符串
     */
    public static String formatTime(LocalTime localTime) {
        return localTime.format(TIME_FORMATTER);
    }

    /**
     * 格式化 LocalTime 对象为字符串，格式为HHmmss
     *
     * @param localTime LocalTime 对象
     * @return 格式化后的时间字符串
     */
    public static String formatCompactTime(LocalTime localTime) {
        return localTime.format(COMPACT_TIME_FORMATTER);
    }

    /**
     * 格式化 LocalDateTime 对象为字符串，格式为yyyy-MM-dd HH:mm:ss
     *
     * @param localDateTime LocalDateTime 对象
     * @return 格式化后的日期时间字符串
     */
    public static String formatDateTime(LocalDateTime localDateTime) {
        return localDateTime.format(DATETIME_FORMATTER);
    }

    /**
     * 格式化 LocalDateTime 对象为字符串，格式为yyyy-MM-dd HH:mm:ss
     *
     * @param localDateTime LocalDateTime 对象
     * @return 格式化后的日期时间字符串
     */
    public static String formatCompactDateTime(LocalDateTime localDateTime) {
        return localDateTime.format(COMPACT_DATETIME_FORMATTER);
    }

    /**
     * 计算两个日期之间的天数差
     *
     * @param startDate 起始日期
     * @param endDate   结束日期
     * @return 天数差
     */
    public static long between(Date startDate, Date endDate) {
        return ChronoUnit.DAYS.between(convert(startDate), convert(endDate));
    }

    /**
     * 计算两个日期之间的天数差
     *
     * @param startDate 起始日期
     * @param endDate   结束日期
     * @return 天数差
     */
    public static long between(LocalDate startDate, LocalDate endDate) {
        return ChronoUnit.DAYS.between(startDate, endDate);
    }

    /**
     * 计算两个时间点之间的时间差（小时）
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 时间差（小时）
     */
    public static double between(LocalTime startTime, LocalTime endTime) {
        return Duration.between(startTime, endTime).toHours();
    }

    /**
     * 获取指定年月日的 java.util.Date 对象，默认时间为当天的开始时间 (00:00:00)
     *
     * @param year  年份
     * @param month 月份（1-12）
     * @param day   日（1-31，取决于月份）
     * @return 指定年月日的 java.util.Date 对象
     */
    public static Date getDate(int year, int month, int day) {
        LocalDate localDate = LocalDate.of(year, month, day);
        return convert(localDate.atStartOfDay());
    }

    /**
     * 获取指定年月日的 java.util.Date 对象，时间为当天的结束时间 (23:59:59)
     *
     * @param year  年份
     * @param month 月份（1-12）
     * @param day   日（1-31，取决于月份）
     * @return 指定年月日的 java.util.Date 对象
     */
    public static Date getDateEndOfDay(int year, int month, int day) {
        LocalDate localDate = LocalDate.of(year, month, day);
        return convert(LocalDateTime.of(localDate, LocalTime.MAX));
    }

    /**
     * 将 LocalDate 转换为 java.util.Date
     *
     * @param localDate LocalDate 对象
     * @return java.util.Date 对象
     */
    public static Date convert(LocalDate localDate) {
        return java.util.Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 将 LocalDateTime 转换为 java.util.Date
     *
     * @param localDateTime LocalDateTime 对象
     * @return java.util.Date 对象
     */
    public static Date convert(LocalDateTime localDateTime) {
        return java.util.Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 将 java.util.Date 转换为 LocalDateTime
     *
     * @param utilDate java.util.Date 对象
     * @return LocalDateTime 对象
     */
    public static LocalDateTime convert(Date utilDate) {
        return utilDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

}
